package momo.multitree.visual;

import java.io.PrintWriter;
import java.util.Set;

import momo.multitree.structure.Edge;
import momo.multitree.structure.Graph;
import momo.multitree.structure.Node;

public class GraphVizGraphOutput implements GraphVisualOutput
{
	private Graph g;
	
	public GraphVizGraphOutput()
	{
	}
	
	public void setGraph(Graph g)
	{
		this.g = g;
	}
	
	public void setDecimalPlace()
	{
	}

	public void output(String filename) throws Exception
	{
		if (g == null)
			throw new RuntimeException("Graph is null");
		
		StringBuffer buffer = new StringBuffer();
		outputNode(buffer);
		outputEdge(buffer);
		outputHeaderTrailer(buffer);
		outputToFile("visual/GraphViz/"+filename+".gv", buffer.toString());
	}
	
	private void outputHeaderTrailer(StringBuffer buffer)
	{
		buffer.insert(0, "graph G {\n");
		buffer.append("}");
	}
	
	private void outputNode(StringBuffer buffer)
	{
		Set<Node> nodes = g.getNodes();
		for(Node n: nodes)
		{
			String id = n.getId();
			double workload = rdTo(n.getWorkloadRate(), 2);
			double stability = rdTo(n.getStability(), 2);
			buffer.append(id + " [label=\""+id+"\\n["+workload+", "+stability+"]\"];\n");
		}
	}
	
	private void outputEdge(StringBuffer buffer)
	{
		Set<Edge> edges = g.getEdges();
		for(Edge e: edges)
		{
			Node h = e.getHeadNode();
			Node t = e.getTailNode();
			double latency = rdTo(e.getLatency(h), 2);
			double cost = rdTo(e.getCost(h), 2);
			buffer.append(h.getId() + " -- " + t.getId() 
					+ " [label=\"("+latency+", "+cost+")\"];\n" );
		}
	}
	
	private void outputToFile(String filename, String data) throws Exception
	{
		PrintWriter out = new PrintWriter(filename);
		out.println(data);
		out.flush();
		out.close();
	}
	
	private double rdTo(double value, int decimalPlace)
	{
		double times = Math.pow(10, decimalPlace);
		double newVal = Math.round(value * times)/times;
		return newVal;
	}
}
